using Test
using JSON

# Import the NUMSCALE module directly
include("../../src/DataIO/NUMSCALETables.jl")
using .NUMSCALETables

@testset "NUMSCALE Tables" begin
    @testset "Table Loading" begin
        # Test default table loading
        table = load_default_numscale_table()

        @test table isa NUMSCALETable
        @test table.default_multiplier == 1.2
        @test table.interpolation == :linear

        # Should have loaded platforms
        @test length(table.platforms) > 0
        @test length(table.platforms) >= 20  # Should have at least 20 platforms

        # Check some key platforms exist
        @test haskey(table.platforms, 220)  # SHIP
        @test haskey(table.platforms, 242)  # SATWND IR
        @test haskey(table.platforms, 280)  # AIRCRAFT
    end

    @testset "Platform 220 (SHIP) Multipliers" begin
        table = load_default_numscale_table()

        # SHIP at surface (1000 hPa = 100000 Pa)
        mult = compute_sigma_multiplier(table, 220, 100000.0)
        @test mult ≈ 1.5 atol=0.01

        # SHIP at mid-level (500 hPa = 50000 Pa)
        mult = compute_sigma_multiplier(table, 220, 50000.0)
        @test 1.4 <= mult <= 1.5

        # SHIP at upper level (200 hPa = 20000 Pa)
        mult = compute_sigma_multiplier(table, 220, 20000.0)
        @test 1.5 <= mult <= 2.0
    end

    @testset "Platform 242 (SATWND IR) Multipliers" begin
        table = load_default_numscale_table()

        # SATWND at low level (1000 hPa)
        mult = compute_sigma_multiplier(table, 242, 100000.0)
        @test mult ≈ 3.5 atol=0.1

        # SATWND at mid-level (700 hPa = 70000 Pa)
        mult = compute_sigma_multiplier(table, 242, 70000.0)
        @test 1.0 <= mult <= 5.0  # Should be between reasonable bounds
    end

    @testset "Platform 280 (AIRCRAFT) Multipliers" begin
        table = load_default_numscale_table()

        # Aircraft at surface
        mult = compute_sigma_multiplier(table, 280, 100000.0)
        @test mult ≈ 1.8 atol=0.1

        # Aircraft at cruise level (300 hPa = 30000 Pa)
        mult = compute_sigma_multiplier(table, 280, 30000.0)
        @test 1.5 <= mult <= 2.8
    end

    @testset "Interpolation" begin
        table = load_default_numscale_table()

        # Test interpolation between exact levels for platform 220
        # At 1000 hPa: mult = 1.5
        # At 950 hPa: mult = 1.2

        mult_1000 = compute_sigma_multiplier(table, 220, 100000.0)
        mult_950 = compute_sigma_multiplier(table, 220, 95000.0)
        mult_975 = compute_sigma_multiplier(table, 220, 97500.0)  # Halfway

        # Interpolated value should be between the two bounds
        @test mult_950 <= mult_975 <= mult_1000

        # For linear interpolation, should be approximately the average
        expected = (mult_1000 + mult_950) / 2.0
        @test mult_975 ≈ expected atol=0.05
    end

    @testset "Boundary Conditions" begin
        table = load_default_numscale_table()

        # Pressure above table range (should use highest pressure entry)
        mult_high = compute_sigma_multiplier(table, 220, 120000.0)
        mult_1100 = compute_sigma_multiplier(table, 220, 110000.0)
        @test mult_high == mult_1100

        # Pressure below table range (should use lowest pressure entry)
        mult_low = compute_sigma_multiplier(table, 220, 100.0)  # 1 Pa
        mult_0 = compute_sigma_multiplier(table, 220, 0.0)
        @test mult_low == mult_0
    end

    @testset "Unknown Platform" begin
        table = load_default_numscale_table()

        # Platform not in table should return default multiplier
        mult = compute_sigma_multiplier(table, 999, 50000.0)
        @test mult == table.default_multiplier
        @test mult == 1.2
    end

    @testset "Edge Cases" begin
        table = load_default_numscale_table()

        # Zero pressure (should handle gracefully)
        mult = compute_sigma_multiplier(table, 220, 0.0)
        @test mult > 0.0
        @test isfinite(mult)

        # Very high pressure (below sea level)
        mult = compute_sigma_multiplier(table, 220, 120000.0)
        @test mult > 0.0
        @test isfinite(mult)
    end

    @testset "Consistency Checks" begin
        table = load_default_numscale_table()

        # Test that multipliers are monotonic or reasonable for each platform
        for (platform, entries) in table.platforms
            if length(entries) < 2
                continue
            end

            # All multipliers should be positive
            for entry in entries
                @test all(entry.multipliers .> 0.0)
                @test entry.pressure_pa >= 0.0
            end

            # Pressures should be sorted in descending order
            pressures = [e.pressure_pa for e in entries]
            @test issorted(pressures, rev=true)
        end
    end

    @testset "CSV vs JSON Consistency" begin
        # Load from JSON (default)
        json_table = load_default_numscale_table()

        # Verify a few key values match expected from CSV
        # Platform 220, 1000 hPa should be 1.5
        mult = compute_sigma_multiplier(json_table, 220, 100000.0)
        @test mult ≈ 1.5 atol=0.01

        # Platform 242, 1100 hPa should be 3.5
        mult = compute_sigma_multiplier(json_table, 242, 110000.0)
        @test mult ≈ 3.5 atol=0.01

        # Platform 280, 1000 hPa should be 1.8
        mult = compute_sigma_multiplier(json_table, 280, 100000.0)
        @test mult ≈ 1.8 atol=0.01
    end

    @testset "Performance" begin
        table = load_default_numscale_table()

        # Single lookup should be fast (< 1 microsecond)
        t = @elapsed begin
            for i in 1:1000
                compute_sigma_multiplier(table, 220, 50000.0)
            end
        end

        avg_time_us = (t / 1000.0) * 1e6
        @test avg_time_us < 10.0  # Should be < 10 microseconds per lookup

        println("Average NUMSCALE lookup time: $(round(avg_time_us, digits=2)) μs")
    end

    @testset "Real-World Scenarios" begin
        table = load_default_numscale_table()

        # Scenario 1: RAOB balloon ascent
        # Note: Platform 120 may not be in wind errtable, should use default
        mult = compute_sigma_multiplier(table, 120, 100000.0)  # Surface
        @test mult >= 1.0

        # Scenario 2: Aircraft descent profile
        pressures = [30000.0, 50000.0, 70000.0, 85000.0, 100000.0]
        mults = [compute_sigma_multiplier(table, 280, p) for p in pressures]

        # All multipliers should be reasonable (1.0-3.0 range)
        @test all(1.0 .<= mults .<= 3.0)
        @test all(isfinite.(mults))

        # Scenario 3: Satellite wind at different levels
        satwnd_pressures = [100000.0, 70000.0, 50000.0, 30000.0]
        satwnd_mults = [compute_sigma_multiplier(table, 242, p) for p in satwnd_pressures]

        @test all(1.0 .<= satwnd_mults .<= 4.0)
        @test all(isfinite.(satwnd_mults))
    end
end

println("\n✓ All NUMSCALE table tests passed!")
